﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Models;

namespace ConcreteService
{
    public class CacheManager
    {
        public static void Put<T>(T obj)
        {
            string key = GetKey(obj);
            if (string.IsNullOrWhiteSpace(key))
                return;

            ICache cache = ServiceFactory.CreateInstance<ICache>();
            cache.Put(key, obj);
        }

        public static T Get<T>(string key)
        {
            if (GetCacheAttr(typeof(T)) == null)
                return default(T);

            ICache cache = ServiceFactory.CreateInstance<ICache>();
            return cache.Get<T>(key.ToString());
        }

        public static List<T> List<T>()
        {
            if (GetCacheAttr(typeof(T)) == null)
                return null;

            ICache cache = ServiceFactory.CreateInstance<ICache>();
            return cache.List<T>();
        }

        public static void Delete<T>(string key)
        {
            if (GetCacheAttr(typeof(T)) == null)
                return;

            ICache cache = ServiceFactory.CreateInstance<ICache>();
            cache.Delete<T>(key);
        }

        public static void Clear<T>()
        {
            if (GetCacheAttr(typeof(T)) == null)
                return;

            ICache cache = ServiceFactory.CreateInstance<ICache>();
            cache.Clear<T>();
        }

        private static CacheAttr GetCacheAttr(Type type)
        {
            var attr = (CacheAttr)Attribute.GetCustomAttribute(type, typeof(CacheAttr));
            return attr;
        }

        private static string GetKey<T>(T obj)
        {
            Type type = obj.GetType();
            var attr = GetCacheAttr(type);
            if (attr == null)
                return null;

            var propInfo = type.GetProperty(attr.PrimaryKey);
            if (propInfo == null)
                return null;

            var val = propInfo.GetValue(obj);
            if (val == null)
                return null;

            return val.ToString();
        }
    }
}
